package com.lee.common.util;


public final class CryptPasswd {

    protected int[] key_schedule = new int[32];
    protected int   IV0 = 0;
    protected int   IV1 = 0;
    public byte[] byteKey = ("CORACLE-YK".substring(0,8)).getBytes();

    /**
    * 加密、解密主要实现部分
    * @param tmpsrc 源数据
    * @param srcOff 源数据偏移量(一般为0)
    * @param dest 目标数据
    * @param destOff 目标数据偏移量(一般为0)
    * @param len 数据的长度
    * @param bCrypt 是否加密过程，false表示为解密过程
    * @return 处理后的结果
    */
    public char[] encrypt(byte[] tmpsrc, int srcOff, byte[] dest, int destOff, int len,boolean bCrypt)
    {
        int[]  out = new int[2];
        int iv0 = IV0;
        int iv1 = IV1;
        int end = srcOff + len;
        char[] cTmp;
        int iCtmp;

        if( bCrypt)
        {
            cTmp = new char[(tmpsrc.length + 8 - ( tmpsrc.length % 8))*2];
        }
        else
        {
            cTmp = null;
        }

        setKey(byteKey);

        byte[] src;
        if ( tmpsrc.length % 8 == 0)
        {
            src = new byte[tmpsrc.length];
        }
        else
        {
            src = new byte[tmpsrc.length + 8 - ( tmpsrc.length % 8)];
        }

        try
        {
            for( int num = 0; num < tmpsrc.length; num++)
            {
                src[num]=tmpsrc[num];
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        iCtmp = 0;
        for(int si = srcOff, di = destOff; si < end; si += 8, di += 8)
        {
            iv0 = ((src[si+3] & 0xff) | ((src[si+2] & 0xff) << 8) |
            (( src[si+1] & 0xff) << 16) | ((src[si] & 0xff) << 24));

            iv1 = ((src[si+7] & 0xff)|((src[si+6] & 0xff) << 8) |
                   (( src[si+5] & 0xff) << 16) | ((src[si+4] & 0xff) << 24));

            encrypt(iv0, iv1, out,bCrypt);
            iv0 = out[0];
            iv1 = out[1];

            if( bCrypt )
            {
                char[] cc=new char[8];

                cc = output0x(iv1);
                for(int i = 0;i < 8;i++)
                {
                    cTmp[iCtmp++] = cc[i];
                }

                cc = output0x(iv0);
                for(int i = 0;i < 8;i++)
                {
                    cTmp[iCtmp++] = cc[i];
                }
            }

            dest[di+7] = (byte)( iv0         & 0xff);
            dest[di+6] = (byte)((iv0 >>> 8 ) & 0xff);
            dest[di+5] = (byte)((iv0 >>> 16) & 0xff);
            dest[di+4] = (byte)((iv0 >>> 24) & 0xff);
            dest[di+3] = (byte)( iv1         & 0xff);
            dest[di+2] = (byte)((iv1 >>> 8 ) & 0xff);
            dest[di+1] = (byte)((iv1 >>> 16) & 0xff);
            dest[di] = (byte)((iv1 >>> 24) & 0xff);
        }

        IV0 = iv0;
        IV1 = iv1;

        return cTmp;
    }

    /**
     * 设置KEY值
     * @param key1 KEY值
     */
    public void setKey(byte[] key1)
    {
        int i, c, d, t, t2, shifts;

        c = (((key1[0] & 0xff) << 24) | ((key1[1] & 0xff) << 16) |
             ((key1[2] & 0xff) <<  8) | (key1[3] & 0xff));
        d = (((key1[4] & 0xff) << 24) | ((key1[5] & 0xff) << 16) |
             ((key1[6] & 0xff) <<  8) | (key1[7] & 0xff) );

        shifts = 0x7efc; //相当于将C中的数组倒过来

        t = (( c >>> 4 ) ^ d) & 0x0f0f0f0f;
        d ^= t;
        c ^= t << 4;

        t = ((c  << 18 ) ^ c ) & 0xcccc0000;
        c ^= t | ( t >>> 18);

        t = ((d  << 18 ) ^ d ) & 0xcccc0000;
        d ^= t | ( t >>> 18);

        t = ((c  << 9 ) ^ c ) & 0xaa00aa00;
        c ^= t | ( t >>> 9);

        t = ((d  << 9 ) ^ d ) & 0xaa00aa00;
        d ^= t | ( t >>> 9);

        t = 	((d & 0x000000ff) << 24 )
          |	((d & 0x0000ff00) << 8 )
          |	((d & 0x00ff0000) >>> 8)
          |	((d & 0xff000000) >>> 24);
        t2= c;

        c = t >>> 4;

        d = ((t2 & 0x00ffffff) << 4) | (t & 0x0000000f);

        for(i = 0; i < 16; i++)
        {
            if((shifts & 1) != 0)
            {
            c = (c << 2) | (c >>> 26);
            d = (d << 2) | (d >>> 26);
        }
        else
        {
            c = ((c << 1) | (c >>> 27));
            d = ((d << 1) | (d >>> 27));
        }
        shifts >>>= 1;
        c &= 0x0fffffff;
        d &= 0x0fffffff;


        t = des_skb[0][(c >>> 22) & 0x3f						] |
            des_skb[1][((c >>> 16) & 0x30) | ((c >>> 15) & 0x0f)] |
            des_skb[2][((c >>> 9) & 0x3c) | ((c >>> 8) & 0x3)	] |
            des_skb[3][((c >>> 2) & 0x20) | ((c >>> 1) & 0x18) | ( c & 0x7)];

        t2 = des_skb[4][(d >>> 22) & 0x3f						] |
             des_skb[5][((d >>> 15) & 0x30) | ((d >>> 14) & 0x0f)] |
             des_skb[6][(d >>> 7) & 0x3f							] |
             des_skb[7][((d >>> 1) & 0x3c) | (d & 0x3)];

        key_schedule[i * 2]		= ( t & 0xff000000) | (( t & 0x0000ff00) << 8)
                             | ((t2 & 0xff000000) >>> 16) + (( t2 & 0x0000ff00) >>> 8);
        key_schedule[(i * 2)+1]	= ((t & 0x00ff0000) << 8) | ((t & 0x000000ff) << 16)
                                | ((t2 & 0x00ff0000) >>> 8) | ( t2 & 0x000000ff);

        //前面中t值不同，t2值相同，但是key_schedule相同，暂时不管t为什么不同
        //注：t“|”操作的四个部分相同，但结果不同
        }

    }

    /**
    * 加密、解密过程
    * @param l 第一个8位16进制数
    * @param r 第二个8位16进制数
    * @param out 处理后的数(数组)
    * @param bCrypt
    */
    public void encrypt(int l, int r, int[] out,boolean bCrypt)
    {
          int t = 0, u = 0, i;

          t = (( l >>> 4 ) ^ r ) & 0x0f0f0f0f;
          r ^= t;
          l ^= t << 4;

          t = (( l >>> 16 ) ^ r ) & 0x0000ffff;
          r ^= t;
          l ^= t << 16;

          t = (( r >>> 2 ) ^ l ) & 0x33333333;
          l ^= t;
          r ^= t << 2;

          t = (( r >>> 8 ) ^ l ) & 0x00ff00ff;
          l ^= t;
          r ^= t << 8;

          t = (( l >>> 1 ) ^ r ) & 0x55555555;
          r ^= t;
          l ^= t << 1;

       l = l & 0xffffffff;
       r = r & 0xffffffff;

           if(bCrypt) /* 加密*/
           {
              for ( i = 0 ;i< 32 ; i+= 4)
              {
                  //第一次进入时，l和r均相同

                  t = (( r >>> 3) | (r << 29)) ^ key_schedule[i + 0];
                  u = (( r << 1) | (r >>> 31)) ^ key_schedule[i + 1];

                  l ^=
                              (des_SPtrans[1][(u >>> 24) & 0x3f] | des_SPtrans[3][(u >>> 16) & 0x3f] |
                             des_SPtrans[5][(u >>>  8) & 0x3f] | des_SPtrans[7][(u       ) & 0x3f] |
                             des_SPtrans[0][(t >>> 24) & 0x3f] | des_SPtrans[2][(t >>> 16) & 0x3f] |
                             des_SPtrans[4][(t >>>  8) & 0x3f] | des_SPtrans[6][(t       ) & 0x3f]);


              t = (( l >>> 3) | (l << 29)) ^ key_schedule[i + 2];
                  u = (( l << 1) | (l >>> 31)) ^ key_schedule[i + 3];

                  r ^=
                              (des_SPtrans[1][(u >>> 24) & 0x3f] | des_SPtrans[3][(u >>> 16) & 0x3f] |
                             des_SPtrans[5][(u >>>  8) & 0x3f] | des_SPtrans[7][(u       ) & 0x3f] |
                             des_SPtrans[0][(t >>> 24) & 0x3f] | des_SPtrans[2][(t >>> 16) & 0x3f] |
                             des_SPtrans[4][(t >>>  8) & 0x3f] | des_SPtrans[6][(t       ) & 0x3f]);

               }
          }
          else /*解密*/
          {
              for ( i = 30 ;i >0 ; i-= 4)
              {

                  t = (( r >>> 3) | (r << 29)) ^ key_schedule[i - 0];
                  u = (( r << 1) | (r >>> 31)) ^ key_schedule[i + 1];

                  l ^=
                              (des_SPtrans[1][(u >>> 24) & 0x3f] | des_SPtrans[3][(u >>> 16) & 0x3f] |
                             des_SPtrans[5][(u >>>  8) & 0x3f] | des_SPtrans[7][(u       ) & 0x3f] |
                             des_SPtrans[0][(t >>> 24) & 0x3f] | des_SPtrans[2][(t >>> 16) & 0x3f] |
                             des_SPtrans[4][(t >>>  8) & 0x3f] | des_SPtrans[6][(t       ) & 0x3f]);


              t = (( l >>> 3) | (l << 29)) ^ key_schedule[i - 2];
                  u = (( l << 1) | (l >>> 31)) ^ key_schedule[i - 1];

                  r ^=
                              (des_SPtrans[1][(u >>> 24) & 0x3f] | des_SPtrans[3][(u >>> 16) & 0x3f] |
                             des_SPtrans[5][(u >>>  8) & 0x3f] | des_SPtrans[7][(u       ) & 0x3f] |
                             des_SPtrans[0][(t >>> 24) & 0x3f] | des_SPtrans[2][(t >>> 16) & 0x3f] |
                             des_SPtrans[4][(t >>>  8) & 0x3f] | des_SPtrans[6][(t       ) & 0x3f]);

               }

          }
          l = l & 0xffffffff;
          r = r & 0xffffffff;

          t  = ((r >>> 1) ^ l)  & 0x55555555;
          l ^= t;
          r ^= t << 1;
          t  = ((l >>> 8) ^ r)  & 0x00ff00ff;
          r ^= t;
          l ^= t << 8;
          t  = ((l >>> 2) ^ r)  & 0x33333333;
          r ^= t;
          l ^= t << 2;
          t  = ((r >>> 16) ^ l) & 0x0000ffff;
          l ^= t;
          r ^= t << 16;
          t  = ((r >>> 4) ^ l)  & 0x0f0f0f0f;
          l ^= t;
          r ^= t << 4;

          out[0] = l;
          out[1] = r;
    }

    public char[] output0x(int iSrc)
    {
        int iTmp=0;
        char[] cid= new char[8];

        for( int i = 7;i>=0 ;i--)
        {
            iTmp = iSrc & 0x0000000f;
            switch(iTmp)
            {
                case 0:
                    cid[i]='0';
                    break;
                case 1:
                    cid[i]='1';
                    break;
                case 2:
                    cid[i]='2';
                    break;
                case 3:
                    cid[i]='3';
                    break;
                case 4:
                    cid[i]='4';
                    break;
                case 5:
                    cid[i]='5';
                    break;
                case 6:
                    cid[i]='6';
                    break;
                case 7:
                    cid[i]='7';
                    break;
                case 8:
                    cid[i]='8';
                    break;
                case 9:
                    cid[i]='9';
                    break;
                case 10:
                    cid[i]='A';
                    break;
                case 11:
                    cid[i]='B';
                    break;
                case 12:
                    cid[i]='C';
                    break;
                case 13:
                    cid[i]='D';
                    break;
                case 14:
                    cid[i]='E';
                    break;
                case 15:
                    cid[i]='F';
                    break;
          }

            iSrc = iSrc >>> 4;
        }
        return cid;
     }


     public String decrypt(String strSrc)
     {
         String strResult;
         try
         {
         byte[] src =new byte[strSrc.length()/2];
         byte[] dest =new byte[strSrc.length()/2];


         outputbyte(strSrc,src);
         encrypt(src,0,dest,0,src.length,false);
         int i = 0;
         for(i = 0; i<dest.length; i++)
         {
             if(dest[i] == 0)
                 break;
         }
         strResult = new String(dest,0,i);
         }
         catch(Exception ee)
         {
             return strSrc;
         }
         return strResult;
     }

     public String encrypt(String strSrc)
     {
         byte[] src =new byte[((strSrc.length()/8 == 0) && (strSrc.length() >=8))
                            ? strSrc.length() : strSrc.length() + 8 - (strSrc.length()%8)];
         byte[] dest =new byte[((strSrc.length()/8 == 0) && (strSrc.length() >=8))
                            ? strSrc.length() : strSrc.length() + 8 - (strSrc.length()%8)];
         String strResult;

         src = strSrc.getBytes();
         char[] o = encrypt(src,0,dest,0,src.length,true);
         int i = 0;
         for(i = 0; i<o.length; i++)
         {
             if(o[i] == 0)
                 break;
         }
         strResult = new String(o,0,i);

         return strResult;
     }

     public void outputbyte(String str0x,byte[] dest)
     {
         for(int i=0; i< str0x.length()/2; i++)
         {
             dest[i] = (byte)(c2i(str0x.charAt(i*2)) * 16 + c2i(str0x.charAt(i*2 + 1)));
         }
    }

    public int c2i(char c)
    {
      int ides=0;
      switch(c)
      {
          case '1':	ides=1;	break;
          case '2':	ides=2;	break;
          case '3':	ides=3;	break;
          case '4':	ides=4;	break;
          case '5':	ides=5;	break;
          case '6':	ides=6;	break;
          case '7':	ides=7;	break;
          case '8':	ides=8;	break;
          case '9':	ides=9;	break;
          case 'a':
          case 'A':	ides=10;break;
          case 'b':
          case 'B':	ides=11;break;
          case 'c':
          case 'C':	ides=12;break;
          case 'd':
          case 'D':	ides=13;break;
          case 'e':
          case 'E':	ides=14;break;
          case 'f':
          case 'F':	ides=15;break;
      }
      return ides;
    }

    /* Table for key generation.  This used to be in sk.h.
    * Copyright (C) 1993 Eric Young - see README for more details
    */
    final static int des_SPtrans[][]={
    {
    /* s_box & P perm 0
    0x00000000, 0x00000002, 0x00000200, 0x00000202,
    0x00008000, 0x00008002, 0x00008200, 0x00008202,
    0x00800000, 0x00800002, 0x00800200, 0x00800202,
    0x00808000, 0x00808002, 0x00808200, 0x00808202,
    */
    0x00808200, 0x00000000, 0x00008000, 0x00808202,
    0x00808002, 0x00008202, 0x00000002, 0x00008000,
    0x00000200, 0x00808200, 0x00808202, 0x00000200,
    0x00800202, 0x00808002, 0x00800000, 0x00000002,
    0x00000202, 0x00800200, 0x00800200, 0x00008200,
    0x00008200, 0x00808000, 0x00808000, 0x00800202,
    0x00008002, 0x00800002, 0x00800002, 0x00008002,
    0x00000000, 0x00000202, 0x00008202, 0x00800000,
    0x00008000, 0x00808202, 0x00000002, 0x00808000,
    0x00808200, 0x00800000, 0x00800000, 0x00000200,
    0x00808002, 0x00008000, 0x00008200, 0x00800002,
    0x00000200, 0x00000002, 0x00800202, 0x00008202,
    0x00808202, 0x00008002, 0x00808000, 0x00800202,
    0x00800002, 0x00000202, 0x00008202, 0x00808200,
    0x00000202, 0x00800200, 0x00800200, 0x00000000,
    0x00008002, 0x00008200, 0x00000000, 0x00808002,
    },{

    /* s_box &P perm 1
    0x00000000, 0x00004000, 0x40000000, 0x40004000,
    0x00000010, 0x00004010, 0x40000010, 0x40004010,
    0x00080000, 0x00084000, 0x40080000, 0x40084000,
    0x00080010, 0x00084010, 0x40080010, 0x40084010,
    */
    0x40084010, 0x40004000, 0x00004000, 0x00084010,
    0x00080000, 0x00000010, 0x40080010, 0x40004010,
    0x40000010, 0x40084010, 0x40084000, 0x40000000,
    0x40004000, 0x00080000, 0x00000010, 0x40080010,
    0x00084000, 0x00080010, 0x40004010, 0x00000000,
    0x40000000, 0x00004000, 0x00084010, 0x40080000,
    0x00080010, 0x40000010, 0x00000000, 0x00084000,
    0x00004010, 0x40084000, 0x40080000, 0x00004010,
    0x00000000, 0x00084010, 0x40080010, 0x00080000,
    0x40004010, 0x40080000, 0x40084000, 0x00004000,
    0x40080000, 0x40004000, 0x00000010, 0x40084010,
    0x00084010, 0x00000010, 0x00004000, 0x40000000,
    0x00004010, 0x40084000, 0x00080000, 0x40000010,
    0x00080010, 0x40004010, 0x40000010, 0x00080010,
    0x00084000, 0x00000000, 0x40004000, 0x00004010,
    0x40000000, 0x40080010, 0x40084010, 0x00084000,
    },{

    /* s_box &P perm 2
    0x00000000, 0x04000000, 0x00000004, 0x04000004,
    0x00010000, 0x04010000, 0x00010004, 0x04010004,
    0x00000100, 0x04000100, 0x00000104, 0x04000104,
    0x00010100, 0x04010100, 0x00010104, 0x04010104,
    */
    0x00000104, 0x04010100, 0x00000000, 0x04010004,
    0x04000100, 0x00000000, 0x00010104, 0x04000100,
    0x00010004, 0x04000004, 0x04000004, 0x00010000,
    0x04010104, 0x00010004, 0x04010000, 0x00000104,
    0x04000000, 0x00000004, 0x04010100, 0x00000100,
    0x00010100, 0x04010000, 0x04010004, 0x00010104,
    0x04000104, 0x00010100, 0x00010000, 0x04000104,
    0x00000004, 0x04010104, 0x00000100, 0x04000000,
    0x04010100, 0x04000000, 0x00010004, 0x00000104,
    0x00010000, 0x04010100, 0x04000100, 0x00000000,
    0x00000100, 0x00010004, 0x04010104, 0x04000100,
    0x04000004, 0x00000100, 0x00000000, 0x04010004,
    0x04000104, 0x00010000, 0x04000000, 0x04010104,
    0x00000004, 0x00010104, 0x00010100, 0x04000004,
    0x04010000, 0x04000104, 0x00000104, 0x04010000,
    0x00010104, 0x00000004, 0x04010004, 0x00010100,
    },{

    /* s_box &P perm 3
    0x00000000, 0x80000000, 0x00400000, 0x80400000,
    0x00001000, 0x80001000, 0x00401000, 0x80401000,
    0x00000040, 0x80000040, 0x00400040, 0x80400040,
    0x00001040, 0x80001040, 0x00401040, 0x80401040,
    */
    0x80401000, 0x80001040, 0x80001040, 0x00000040,
    0x00401040, 0x80400040, 0x80400000, 0x80001000,
    0x00000000, 0x00401000, 0x00401000, 0x80401040,
    0x80000040, 0x00000000, 0x00400040, 0x80400000,
    0x80000000, 0x00001000, 0x00400000, 0x80401000,
    0x00000040, 0x00400000, 0x80001000, 0x00001040,
    0x80400040, 0x80000000, 0x00001040, 0x00400040,
    0x00001000, 0x00401040, 0x80401040, 0x80000040,
    0x00400040, 0x80400000, 0x00401000, 0x80401040,
    0x80000040, 0x00000000, 0x00000000, 0x00401000,
    0x00001040, 0x00400040, 0x80400040, 0x80000000,
    0x80401000, 0x80001040, 0x80001040, 0x00000040,
    0x80401040, 0x80000040, 0x80000000, 0x00001000,
    0x80400000, 0x80001000, 0x00401040, 0x80400040,
    0x80001000, 0x00001040, 0x00400000, 0x80401000,
    0x00000040, 0x00400000, 0x00001000, 0x00401040,
    },{

    /* s_box &P perm 4
    0x00000000, 0x20000000, 0x00000080, 0x20000080,
    0x00040000, 0x20040000, 0x00040080, 0x20040080,
    0x01000000, 0x21000000, 0x01000080, 0x21000080,
    0x01040000, 0x21040000, 0x01040080, 0x21040080,
    */
    0x00000080, 0x01040080, 0x01040000, 0x21000080,
    0x00040000, 0x00000080, 0x20000000, 0x01040000,
    0x20040080, 0x00040000, 0x01000080, 0x20040080,
    0x21000080, 0x21040000, 0x00040080, 0x20000000,
    0x01000000, 0x20040000, 0x20040000, 0x00000000,
    0x20000080, 0x21040080, 0x21040080, 0x01000080,
    0x21040000, 0x20000080, 0x00000000, 0x21000000,
    0x01040080, 0x01000000, 0x21000000, 0x00040080,
    0x00040000, 0x21000080, 0x00000080, 0x01000000,
    0x20000000, 0x01040000, 0x21000080, 0x20040080,
    0x01000080, 0x20000000, 0x21040000, 0x01040080,
    0x20040080, 0x00000080, 0x01000000, 0x21040000,
    0x21040080, 0x00040080, 0x21000000, 0x21040080,
    0x01040000, 0x00000000, 0x20040000, 0x21000000,
    0x00040080, 0x01000080, 0x20000080, 0x00040000,
    0x00000000, 0x20040000, 0x01040080, 0x20000080,
    },{

    /* s_box &P perm 5
    0x00000000, 0x00002000, 0x00200000, 0x00202000,
    0x00000008, 0x00002008, 0x00200008, 0x00202008,
    0x10000000, 0x10002000, 0x10200000, 0x10202000,
    0x10000008, 0x10002008, 0x10200008, 0x10202008,
    */
    0x10000008, 0x10200000, 0x00002000, 0x10202008,
    0x10200000, 0x00000008, 0x10202008, 0x00200000,
    0x10002000, 0x00202008, 0x00200000, 0x10000008,
    0x00200008, 0x10002000, 0x10000000, 0x00002008,
    0x00000000, 0x00200008, 0x10002008, 0x00002000,
    0x00202000, 0x10002008, 0x00000008, 0x10200008,
    0x10200008, 0x00000000, 0x00202008, 0x10202000,
    0x00002008, 0x00202000, 0x10202000, 0x10000000,
    0x10002000, 0x00000008, 0x10200008, 0x00202000,
    0x10202008, 0x00200000, 0x00002008, 0x10000008,
    0x00200000, 0x10002000, 0x10000000, 0x00002008,
    0x10000008, 0x10202008, 0x00202000, 0x10200000,
    0x00202008, 0x10202000, 0x00000000, 0x10200008,
    0x00000008, 0x00002000, 0x10200000, 0x00202008,
    0x00002000, 0x00200008, 0x10002008, 0x00000000,
    0x10202000, 0x10000000, 0x00200008, 0x10002008,
    },{

    /* s_box &P perm 6
    0x00000000, 0x02000000, 0x00000400, 0x02000400,
    0x00100000, 0x02100000, 0x00100400, 0x02100400,
    0x00000001, 0x02000001, 0x00000401, 0x02000401,
    0x00100001, 0x02100001, 0x00100401, 0x02100401,
    */
    0x00100000, 0x02100001, 0x02000401, 0x00000000,
    0x00000400, 0x02000401, 0x00100401, 0x02100400,
    0x02100401, 0x00100000, 0x00000000, 0x02000001,
    0x00000001, 0x02000000, 0x02100001, 0x00000401,
    0x02000400, 0x00100401, 0x00100001, 0x02000400,
    0x02000001, 0x02100000, 0x02100400, 0x00100001,
    0x02100000, 0x00000400, 0x00000401, 0x02100401,
    0x00100400, 0x00000001, 0x02000000, 0x00100400,
    0x02000000, 0x00100400, 0x00100000, 0x02000401,
    0x02000401, 0x02100001, 0x02100001, 0x00000001,
    0x00100001, 0x02000000, 0x02000400, 0x00100000,
    0x02100400, 0x00000401, 0x00100401, 0x02100400,
    0x00000401, 0x02000001, 0x02100401, 0x02100000,
    0x00100400, 0x00000000, 0x00000001, 0x02100401,
    0x00000000, 0x00100401, 0x02100000, 0x00000400,
    0x02000001, 0x02000400, 0x00000400, 0x00100001,
    },{

    /* s_box &P perm 7
    0x00000000, 0x00000800, 0x00020000, 0x00020800,
    0x00000020, 0x00000820, 0x00020020, 0x00020820,
    0x08000000, 0x08000800, 0x08020000, 0x08020800,
    0x08000020, 0x08000820, 0x08020020, 0x08020820,
    */
    0x08000820, 0x00000800, 0x00020000, 0x08020820,
    0x08000000, 0x08000820, 0x00000020, 0x08000000,
    0x00020020, 0x08020000, 0x08020820, 0x00020800,
    0x08020800, 0x00020820, 0x00000800, 0x00000020,
    0x08020000, 0x08000020, 0x08000800, 0x00000820,
    0x00020800, 0x00020020, 0x08020020, 0x08020800,
    0x00000820, 0x00000000, 0x00000000, 0x08020020,
    0x08000020, 0x08000800, 0x00020820, 0x00020000,
    0x00020820, 0x00020000, 0x08020800, 0x00000800,
    0x00000020, 0x08020020, 0x00000800, 0x00020820,
    0x08000800, 0x00000020, 0x08000020, 0x08020000,
    0x08020020, 0x08000000, 0x00020000, 0x08000820,
    0x00000000, 0x08020820, 0x00020020, 0x08000020,
    0x08020000, 0x08000800, 0x08000820, 0x00000000,
    0x08020820, 0x00020800, 0x00020800, 0x00000820,
    0x00000820, 0x00020020, 0x08000000, 0x08020800,
    } };

    final static int des_skb[][]={
    {
    /* 1 2 3 4 5 6 */
    0x00000000, 0x00040000, 0x01000000, 0x01040000,
    0x00000400, 0x00040400, 0x01000400, 0x01040400,
    0x00200000, 0x00240000, 0x01200000, 0x01240000,
    0x00200400, 0x00240400, 0x01200400, 0x01240400,
    0x00000001, 0x00040001, 0x01000001, 0x01040001,
    0x00000401, 0x00040401, 0x01000401, 0x01040401,
    0x00200001, 0x00240001, 0x01200001, 0x01240001,
    0x00200401, 0x00240401, 0x01200401, 0x01240401,
    0x02000000, 0x02040000, 0x03000000, 0x03040000,
    0x02000400, 0x02040400, 0x03000400, 0x03040400,
    0x02200000, 0x02240000, 0x03200000, 0x03240000,
    0x02200400, 0x02240400, 0x03200400, 0x03240400,
    0x02000001, 0x02040001, 0x03000001, 0x03040001,
    0x02000401, 0x02040401, 0x03000401, 0x03040401,
    0x02200001, 0x02240001, 0x03200001, 0x03240001,
    0x02200401, 0x02240401, 0x03200401, 0x03240401,
    },{
    /* 7 8 10 1 12 13 */
    0x00000000, 0x00000002, 0x00000800, 0x00000802,
    0x08000000, 0x08000002, 0x08000800, 0x08000802,
    0x00010000, 0x00010002, 0x00010800, 0x00010802,
    0x08010000, 0x08010002, 0x08010800, 0x08010802,
    0x00000100, 0x00000102, 0x00000900, 0x00000902,
    0x08000100, 0x08000102, 0x08000900, 0x08000902,
    0x00010100, 0x00010102, 0x00010900, 0x00010902,
    0x08010100, 0x08010102, 0x08010900, 0x08010902,
    0x00000010, 0x00000012, 0x00000810, 0x00000812,
    0x08000010, 0x08000012, 0x08000810, 0x08000812,
    0x00010010, 0x00010012, 0x00010810, 0x00010812,
    0x08010010, 0x08010012, 0x08010810, 0x08010812,
    0x00000110, 0x00000112, 0x00000910, 0x00000912,
    0x08000110, 0x08000112, 0x08000910, 0x08000912,
    0x00010110, 0x00010112, 0x00010910, 0x00010912,
    0x08010110, 0x08010112, 0x08010910, 0x08010912,
    },{
    /* 14 15 1 17 19 20 */
    0x00000000, 0x00000004, 0x00001000, 0x00001004,
    0x10000000, 0x10000004, 0x10001000, 0x10001004,
    0x00000020, 0x00000024, 0x00001020, 0x00001024,
    0x10000020, 0x10000024, 0x10001020, 0x10001024,
    0x00080000, 0x00080004, 0x00081000, 0x00081004,
    0x10080000, 0x10080004, 0x10081000, 0x10081004,
    0x00080020, 0x00080024, 0x00081020, 0x00081024,
    0x10080020, 0x10080024, 0x10081020, 0x10081024,
    0x20000000, 0x20000004, 0x20001000, 0x20001004,
    0x30000000, 0x30000004, 0x30001000, 0x30001004,
    0x20000020, 0x20000024, 0x20001020, 0x20001024,
    0x30000020, 0x30000024, 0x30001020, 0x30001024,
    0x20080000, 0x20080004, 0x20081000, 0x20081004,
    0x30080000, 0x30080004, 0x30081000, 0x30081004,
    0x20080020, 0x20080024, 0x20081020, 0x20081024,
    0x30080020, 0x30080024, 0x30081020, 0x30081024,
    },{
    /* 21 23 2 26 27 28 */
    0x00000000, 0x00100000, 0x00000008, 0x00100008,
    0x00000200, 0x00100200, 0x00000208, 0x00100208,
    0x04000000, 0x04100000, 0x04000008, 0x04100008,
    0x04000200, 0x04100200, 0x04000208, 0x04100208,
    0x00002000, 0x00102000, 0x00002008, 0x00102008,
    0x00002200, 0x00102200, 0x00002208, 0x00102208,
    0x04002000, 0x04102000, 0x04002008, 0x04102008,
    0x04002200, 0x04102200, 0x04002208, 0x04102208,
    0x00020000, 0x00120000, 0x00020008, 0x00120008,
    0x00020200, 0x00120200, 0x00020208, 0x00120208,
    0x04020000, 0x04120000, 0x04020008, 0x04120008,
    0x04020200, 0x04120200, 0x04020208, 0x04120208,
    0x00022000, 0x00122000, 0x00022008, 0x00122008,
    0x00022200, 0x00122200, 0x00022208, 0x00122208,
    0x04022000, 0x04122000, 0x04022008, 0x04122008,
    0x04022200, 0x04122200, 0x04022208, 0x04122208,
    },{
    /* 29 30 3 32 33 34 */
    0x00000000, 0x00000200, 0x00020000, 0x00020200,
    0x00000001, 0x00000201, 0x00020001, 0x00020201,
    0x08000000, 0x08000200, 0x08020000, 0x08020200,
    0x08000001, 0x08000201, 0x08020001, 0x08020201,
    0x00200000, 0x00200200, 0x00220000, 0x00220200,
    0x00200001, 0x00200201, 0x00220001, 0x00220201,
    0x08200000, 0x08200200, 0x08220000, 0x08220200,
    0x08200001, 0x08200201, 0x08220001, 0x08220201,
    0x00000002, 0x00000202, 0x00020002, 0x00020202,
    0x00000003, 0x00000203, 0x00020003, 0x00020203,
    0x08000002, 0x08000202, 0x08020002, 0x08020202,
    0x08000003, 0x08000203, 0x08020003, 0x08020203,
    0x00200002, 0x00200202, 0x00220002, 0x00220202,
    0x00200003, 0x00200203, 0x00220003, 0x00220203,
    0x08200002, 0x08200202, 0x08220002, 0x08220202,
    0x08200003, 0x08200203, 0x08220003, 0x08220203,
    },{
    /* 36 37 3 40 41 42 */
    0x00000000, 0x00000010, 0x20000000, 0x20000010,
    0x00100000, 0x00100010, 0x20100000, 0x20100010,
    0x00000800, 0x00000810, 0x20000800, 0x20000810,
    0x00100800, 0x00100810, 0x20100800, 0x20100810,
    0x04000000, 0x04000010, 0x24000000, 0x24000010,
    0x04100000, 0x04100010, 0x24100000, 0x24100010,
    0x04000800, 0x04000810, 0x24000800, 0x24000810,
    0x04100800, 0x04100810, 0x24100800, 0x24100810,
    0x00000004, 0x00000014, 0x20000004, 0x20000014,
    0x00100004, 0x00100014, 0x20100004, 0x20100014,
    0x00000804, 0x00000814, 0x20000804, 0x20000814,
    0x00100804, 0x00100814, 0x20100804, 0x20100814,
    0x04000004, 0x04000014, 0x24000004, 0x24000014,
    0x04100004, 0x04100014, 0x24100004, 0x24100014,
    0x04000804, 0x04000814, 0x24000804, 0x24000814,
    0x04100804, 0x04100814, 0x24100804, 0x24100814,
    },{
    /* 44 45 4 47 48 49 */
    0x00000000, 0x00001000, 0x00010000, 0x00011000,
    0x02000000, 0x02001000, 0x02010000, 0x02011000,
    0x00000020, 0x00001020, 0x00010020, 0x00011020,
    0x02000020, 0x02001020, 0x02010020, 0x02011020,
    0x00040000, 0x00041000, 0x00050000, 0x00051000,
    0x02040000, 0x02041000, 0x02050000, 0x02051000,
    0x00040020, 0x00041020, 0x00050020, 0x00051020,
    0x02040020, 0x02041020, 0x02050020, 0x02051020,
    0x00002000, 0x00003000, 0x00012000, 0x00013000,
    0x02002000, 0x02003000, 0x02012000, 0x02013000,
    0x00002020, 0x00003020, 0x00012020, 0x00013020,
    0x02002020, 0x02003020, 0x02012020, 0x02013020,
    0x00042000, 0x00043000, 0x00052000, 0x00053000,
    0x02042000, 0x02043000, 0x02052000, 0x02053000,
    0x00042020, 0x00043020, 0x00052020, 0x00053020,
    0x02042020, 0x02043020, 0x02052020, 0x02053020,
    },{
    /* 50 51 5 53 55 56 */
    0x00000000, 0x00000400, 0x01000000, 0x01000400,
    0x00000100, 0x00000500, 0x01000100, 0x01000500,
    0x10000000, 0x10000400, 0x11000000, 0x11000400,
    0x10000100, 0x10000500, 0x11000100, 0x11000500,
    0x00080000, 0x00080400, 0x01080000, 0x01080400,
    0x00080100, 0x00080500, 0x01080100, 0x01080500,
    0x10080000, 0x10080400, 0x11080000, 0x11080400,
    0x10080100, 0x10080500, 0x11080100, 0x11080500,
    0x00000008, 0x00000408, 0x01000008, 0x01000408,
    0x00000108, 0x00000508, 0x01000108, 0x01000508,
    0x10000008, 0x10000408, 0x11000008, 0x11000408,
    0x10000108, 0x10000508, 0x11000108, 0x11000508,
    0x00080008, 0x00080408, 0x01080008, 0x01080408,
    0x00080108, 0x00080508, 0x01080108, 0x01080508,
    0x10080008, 0x10080408, 0x11080008, 0x11080408,
    0x10080108, 0x10080508, 0x11080108, 0x11080508,
    } };
}